package com.blog.cmrpersonalblog.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blog.cmrpersonalblog.dto.comment.request.CommentQueryRequest;
import com.blog.cmrpersonalblog.dto.comment.responst.CommentManagementResponse;
import com.blog.cmrpersonalblog.dto.comment.request.LatestCommentsRequest;
import com.blog.cmrpersonalblog.dto.comment.request.PopularCommentsRequest;
import com.blog.cmrpersonalblog.dto.article.request.ArticleCommentListRequest;
import com.blog.cmrpersonalblog.dto.article.response.ArticleCommentResponse;
import com.blog.cmrpersonalblog.entity.Comment;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

/**
 * 评论Mapper接口
 */
public interface CommentMapper extends BaseMapper<Comment> {

    /**
     * 分页查询评论管理列表
     * @param page 分页对象
     * @param query 查询条件
     * @return 评论管理列表
     */
    IPage<CommentManagementResponse> selectCommentManagementPage(Page<CommentManagementResponse> page, 
                                                                 @Param("query") CommentQueryRequest query);

    /**
     * 获取评论详情（包含用户和文章信息）
     * @param commentId 评论ID
     * @return 评论详情
     */
    CommentManagementResponse selectCommentDetailById(@Param("commentId") Long commentId);

    /**
     * 获取评论树形结构
     * @param articleId 文章ID
     * @param rootId 根评论ID（可选）
     * @return 评论树
     */
    List<CommentManagementResponse> selectCommentTree(@Param("articleId") Long articleId, 
                                                      @Param("rootId") Long rootId);

    /**
     * 获取子评论列表
     * @param parentId 父评论ID
     * @return 子评论列表
     */
    List<CommentManagementResponse> selectChildComments(@Param("parentId") Long parentId);

    /**
     * 批量更新评论状态
     * @param commentIds 评论ID列表
     * @param status 目标状态
     * @return 更新数量
     */
    int batchUpdateCommentStatus(@Param("commentIds") List<Long> commentIds,
                                @Param("status") Integer status);

    /**
     * 批量标记敏感评论
     * @param commentIds 评论ID列表
     * @param isSensitive 是否敏感
     * @param sensitiveType 敏感类型
     * @return 更新数量
     */
    int batchUpdateSensitiveStatus(@Param("commentIds") List<Long> commentIds, 
                                  @Param("isSensitive") Integer isSensitive,
                                  @Param("sensitiveType") String sensitiveType);

    /**
     * 批量删除评论
     * @param commentIds 评论ID列表
     * @return 删除数量
     */
    int batchDeleteComments(@Param("commentIds") List<Long> commentIds);



    /**
     * 获取评论统计信息
     * @return 统计信息
     */
    Map<String, Object> selectCommentStatistics();



    /**
     * 获取敏感评论数量
     * @return 敏感评论数量
     */
    Long selectSensitiveCommentCount();

    /**
     * 获取评论状态分布
     * @return 状态分布
     */
    List<Map<String, Object>> selectCommentStatusDistribution();

    /**
     * 获取敏感词类型分布
     * @return 敏感词类型分布
     */
    List<Map<String, Object>> selectSensitiveTypeDistribution();

    /**
     * 分页获取最新评论列表
     * @param page 分页对象
     * @param request 查询条件
     * @return 最新评论分页列表
     */
    IPage<CommentManagementResponse> selectLatestCommentsPage(Page<CommentManagementResponse> page,
                                                              @Param("request") LatestCommentsRequest request);

    /**
     * 分页获取热门评论列表
     * @param page 分页对象
     * @param request 查询条件
     * @return 热门评论分页列表
     */
    IPage<CommentManagementResponse> selectPopularCommentsPage(Page<CommentManagementResponse> page,
                                                               @Param("request") PopularCommentsRequest request);

    /**
     * 搜索评论
     * @param page 分页对象
     * @param keyword 关键词
     * @return 搜索结果
     */
    IPage<CommentManagementResponse> searchComments(Page<CommentManagementResponse> page, 
                                                   @Param("keyword") String keyword);

    /**
     * 获取用户评论管理列表
     * @param page 分页对象
     * @param userId 用户ID
     * @return 用户评论列表
     */
    IPage<CommentManagementResponse> selectUserCommentManagementPage(Page<CommentManagementResponse> page, 
                                                                     @Param("userId") Long userId);

    /**
     * 获取文章评论管理列表
     * @param page 分页对象
     * @param articleId 文章ID
     * @return 文章评论列表
     */
    IPage<CommentManagementResponse> selectArticleCommentManagementPage(Page<CommentManagementResponse> page, 
                                                                        @Param("articleId") Long articleId);

    /**
     * 更新评论统计数据
     * @param commentId 评论ID
     * @param field 字段名
     * @param increment 增量
     */
    void updateCommentStats(@Param("commentId") Long commentId, 
                           @Param("field") String field, 
                           @Param("increment") Integer increment);

    /**
     * 重新计算评论统计数据
     * @param commentId 评论ID
     * @return 更新数量
     */
    int recalculateCommentStats(@Param("commentId") Long commentId);

    /**
     * 获取评论回复路径
     * @param commentId 评论ID
     * @return 回复路径
     */
    String selectCommentPath(@Param("commentId") Long commentId);

    /**
     * 计算评论及其所有子评论的数量
     * @param commentId 评论ID
     * @return 评论总数（包括子评论）
     */
    int countCommentAndReplies(@Param("commentId") Long commentId);

    /**
     * 获取评论及其所有子评论的ID列表（用于删除前处理关联数据）
     * @param commentId 评论ID
     * @return 评论ID列表
     */
    List<Long> selectCommentAndRepliesIds(@Param("commentId") Long commentId);

    /**
     * 硬删除评论及其所有子评论（用户端使用）
     * @param commentId 评论ID
     * @return 删除的评论数量
     */
    int hardDeleteCommentAndReplies(@Param("commentId") Long commentId);

    /**
     * 硬删除单个评论（管理端使用）
     * @param commentId 评论ID
     * @return 删除的评论数量
     */
    int hardDeleteComment(@Param("commentId") Long commentId);

    // ==================== 仪表盘统计功能 ====================

    /**
     * 统计今日新增评论数
     * @return 今日新增评论数
     */
    Long countTodayNewComments();

    /**
     * 统计昨日新增评论数
     * @return 昨日新增评论数
     */
    Long countYesterdayNewComments();

    /**
     * 统计指定日期范围内每日新增评论数
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 每日新增评论数列表
     */
    @MapKey("date")
    List<Map<String, Object>> countDailyNewComments(@Param("startDate") String startDate, @Param("endDate") String endDate);

    /**
     * 统计指定日期范围内每日评论总数
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 每日评论总数列表
     */
    @MapKey("date")
    List<Map<String, Object>> countDailyTotalComments(@Param("startDate") String startDate, @Param("endDate") String endDate);

    /**
     * 更新评论路径
     * @param commentId 评论ID
     * @param path 路径
     * @return 更新数量
     */
    int updateCommentPath(@Param("commentId") Long commentId, @Param("path") String path);

    /**
     * 获取评论的所有子评论ID
     * @param commentId 评论ID
     * @return 子评论ID列表
     */
    List<Long> selectAllChildCommentIds(@Param("commentId") Long commentId);

    /**
     * 根据IP地址获取评论列表
     * @param page 分页对象
     * @param ipAddress IP地址
     * @return 评论列表
     */
    IPage<CommentManagementResponse> selectCommentsByIpAddress(Page<CommentManagementResponse> page, 
                                                              @Param("ipAddress") String ipAddress);

    // ==================== 用户端评论功能 ====================

    /**
     * 分页获取文章评论列表（用户端）
     * @param page 分页对象
     * @param request 查询请求
     * @param userId 当前用户ID（可为null）
     * @return 评论列表
     */
    IPage<ArticleCommentResponse> selectArticleCommentsPage(Page<ArticleCommentResponse> page,
                                                           @Param("request") ArticleCommentListRequest request,
                                                           @Param("userId") Long userId);

    /**
     * 获取文章评论列表（用户端，不分页）
     * @param request 查询请求
     * @param userId 当前用户ID（可为null）
     * @return 评论列表
     */
    List<ArticleCommentResponse> selectArticleComments(@Param("request") ArticleCommentListRequest request,
                                                      @Param("userId") Long userId);

    /**
     * 获取评论回复列表（用户端）
     * @param page 分页对象
     * @param parentId 父评论ID
     * @param userId 当前用户ID（可为null）
     * @return 回复列表
     */
    IPage<ArticleCommentResponse> selectCommentRepliesPage(Page<ArticleCommentResponse> page,
                                                          @Param("parentId") Long parentId,
                                                          @Param("userId") Long userId);


    /**
     * 获取评论详情（用户端）
     * @param commentId 评论ID
     * @param userId 当前用户ID（可为null）
     * @return 评论详情
     */
    ArticleCommentResponse selectCommentDetailForUser(@Param("commentId") Long commentId,
                                                     @Param("userId") Long userId);

    /**
     * 获取评论的子评论数量
     * @param commentId 评论ID
     * @return 子评论数量
     */
    Integer selectCommentChildrenCount(@Param("commentId") Long commentId);

    /**
     * 检查文章是否存在且可评论
     * @param articleId 文章ID
     * @return 是否可评论
     */
    boolean checkArticleCommentable(@Param("articleId") Long articleId);

    /**
     * 根据评论ID列表获取相关的文章ID列表
     * @param commentIds 评论ID列表
     * @return 文章ID列表
     */
    List<Long> selectArticleIdsByCommentIds(@Param("commentIds") List<Long> commentIds);

    /**
     * 分页查询顶级评论
     * @param page 分页对象
     * @param articleId 文章ID
     * @param userId 当前用户ID
     * @param sortSql 排序SQL
     * @return 顶级评论列表
     */
    IPage<ArticleCommentResponse> selectTopLevelCommentsPage(Page<ArticleCommentResponse> page,
                                                           @Param("articleId") Long articleId,
                                                           @Param("userId") Long userId,
                                                           @Param("sortSql") String sortSql);

    /**
     * 根据父评论ID列表查询所有子评论
     * @param parentIds 父评论ID列表
     * @param userId 当前用户ID
     * @param maxLevel 最大层级
     * @param childrenLimit 每层子评论限制数量
     * @return 子评论列表
     */
    List<ArticleCommentResponse> selectChildrenByParentIds(@Param("parentIds") List<Long> parentIds,
                                                          @Param("userId") Long userId,
                                                          @Param("maxLevel") Integer maxLevel,
                                                          @Param("childrenLimit") Integer childrenLimit);

    /**
     * 两层级模式：查询根评论下的所有回复（扁平化）
     * @param parentIds 根评论ID列表
     * @param userId 当前用户ID（可为null）
     * @param childrenLimit 每个根评论的回复数量限制
     * @param replySortSql 回复排序SQL
     * @return 扁平化的回复列表
     */
    List<ArticleCommentResponse> selectFlatRepliesByParentIds(@Param("parentIds") List<Long> parentIds,
                                                             @Param("userId") Long userId,
                                                             @Param("childrenLimit") Integer childrenLimit,
                                                             @Param("replySortSql") String replySortSql);

    /**
     * 更新评论的图片信息
     * @param commentId 评论ID
     * @param images 图片JSON字符串
     * @param imageCount 图片数量
     * @return 更新数量
     */
    int updateCommentImages(@Param("commentId") Long commentId, 
                           @Param("images") String images, 
                           @Param("imageCount") Integer imageCount);
}
